package com.campus.food.controller;

import com.campus.food.config.FileUploadConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件访问控制器
 * 用于访问上传的文件
 * 
 * @author Claude3.7 Sonnet
 * @since 2025-05-29
 */
@Controller
@RequestMapping("/api/file")
public class FileAccessController {
    
    @Autowired
    private FileUploadConfig fileUploadConfig;
    
    // 媒体类型映射
    private static final Map<String, String> MEDIA_TYPE_MAP = new HashMap<>();
    
    static {
        // 初始化媒体类型映射
        MEDIA_TYPE_MAP.put("jpg", "image/jpeg");
        MEDIA_TYPE_MAP.put("jpeg", "image/jpeg");
        MEDIA_TYPE_MAP.put("png", "image/png");
        MEDIA_TYPE_MAP.put("gif", "image/gif");
        MEDIA_TYPE_MAP.put("webp", "image/webp");
        MEDIA_TYPE_MAP.put("pdf", "application/pdf");
        MEDIA_TYPE_MAP.put("doc", "application/msword");
        MEDIA_TYPE_MAP.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        MEDIA_TYPE_MAP.put("xls", "application/vnd.ms-excel");
        MEDIA_TYPE_MAP.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        MEDIA_TYPE_MAP.put("ppt", "application/vnd.ms-powerpoint");
        MEDIA_TYPE_MAP.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
        MEDIA_TYPE_MAP.put("txt", "text/plain");
    }
    
    /**
     * 访问商家图片
     * GET /api/file/merchant/**
     */
    @GetMapping("/merchant/**")
    public ResponseEntity<Resource> getMerchantFile(HttpServletRequest request) {
        return getFile(fileUploadConfig.getMerchantUploadPath(), "/merchant/", request);
    }
    
    /**
     * 访问食品图片
     * GET /api/file/food/**
     */
    @GetMapping("/food/**")
    public ResponseEntity<Resource> getFoodFile(HttpServletRequest request) {
        return getFile(fileUploadConfig.getFoodUploadPath(), "/food/", request);
    }
    
    /**
     * 访问用户头像
     * GET /api/file/avatar/**
     */
    @GetMapping("/avatar/**")
    public ResponseEntity<Resource> getAvatarFile(HttpServletRequest request) {
        return getFile(fileUploadConfig.getAvatarUploadPath(), "/avatar/", request);
    }
    
    /**
     * 访问评论图片
     * GET /api/file/review/**
     */
    @GetMapping("/review/**")
    public ResponseEntity<Resource> getReviewFile(HttpServletRequest request) {
        return getFile(fileUploadConfig.getReviewUploadPath(), "/review/", request);
    }
    
    /**
     * 访问通用文件
     * GET /api/file/common/**
     */
    @GetMapping("/common/**")
    public ResponseEntity<Resource> getCommonFile(HttpServletRequest request) {
        return getFile(fileUploadConfig.getBasePath() + "/common", "/common/", request);
    }
    
    /**
     * 访问自定义路径文件
     * GET /api/file/custom/**
     */
    @GetMapping("/custom/**")
    public ResponseEntity<Resource> getCustomFile(HttpServletRequest request) {
        return getFile(fileUploadConfig.getBasePath(), "/custom/", request);
    }
    
    /**
     * 通用文件访问方法
     * 
     * @param basePath 基础路径
     * @param prefixToRemove URL前缀
     * @param request HTTP请求
     * @return 文件资源
     */
    private ResponseEntity<Resource> getFile(String basePath, String prefixToRemove, HttpServletRequest request) {
        try {
            // 获取完整请求路径
            String requestURI = request.getRequestURI();
            
            // 从URL中提取文件路径
            String relativePath = requestURI.substring(requestURI.indexOf(prefixToRemove) + prefixToRemove.length());
            
            // 安全检查，防止路径遍历攻击
            if (relativePath.contains("..")) {
                return ResponseEntity.badRequest().build();
            }
            
            // 构建文件完整路径
            Path filePath = Paths.get(basePath, relativePath);
            Resource resource = new UrlResource(filePath.toUri());
            
            // 检查文件是否存在
            if (!resource.exists() || !resource.isReadable()) {
                return ResponseEntity.notFound().build();
            }
            
            // 确定文件的媒体类型
            String contentType = determineContentType(relativePath);
            
            // 构建响应头
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + resource.getFilename() + "\"")
                    .body(resource);
            
        } catch (MalformedURLException e) {
            return ResponseEntity.badRequest().build();
        }
    }
    
    /**
     * 根据文件名确定媒体类型
     * 
     * @param filename 文件名
     * @return 媒体类型
     */
    private String determineContentType(String filename) {
        String extension = "";
        int lastDotIndex = filename.lastIndexOf(".");
        if (lastDotIndex > 0) {
            extension = filename.substring(lastDotIndex + 1).toLowerCase();
        }
        
        return MEDIA_TYPE_MAP.getOrDefault(extension, "application/octet-stream");
    }
} 